<?php


namespace app\appapi\controller;


use app\common\model\GoodsModel;
use app\common\model\MoneyLogModel;
use app\common\model\OrderModel;
use app\common\model\OrderReceiptModel;
use app\common\model\StorageLogModel;
use app\common\model\StorageManageModel;
use app\common\model\StorageModel;
use cmf\controller\RestBaseController;
use cmf\controller\RestUserBaseController;
use GuzzleHttp\Client;
use think\Db;
use think\db\Query;

class OrderController extends RestUserBaseController
{
    public function get_order_list()
    {
        $param = $this->request->param();
        $list = OrderModel::where(function (Query $query) use ($param) {
            $query->where('user_id', $this->userId);
            if (!empty($param['type']) && $param['type'] > -1) {
                $query->where('order_status', $param['type']);
            }

            if (!empty($param['order_no'])) {
                $query->where('order_no', $param['order_no']);
            }
            if (!empty($param['times'])) {
                $query->whereBetweenTime('add_time', strtotime($param['times'][0]), strtotime($param['times'][1]));
            }
        })->order('id desc')->paginate()->each(function ($v, $k) {
            $v['cn_status'] = OrderModel::getStatus($v['order_status']);
        });
        $this->success('ok', $list);
    }

    /**
     * 包裹列表
     * @param $type
     * @param $order_no
     * @param $self_order_no
     * @param $delivery_nom
     * @param $p
     * @param array $time
     */
    public function get_order_receipt_list()
    {
        $param = $this->request->param();
        $list = OrderReceiptModel::where(function (Query $query) use ($param) {
            $query->where('user_id', $this->userId)->where('show_status', 1);
            if (!empty($param['type']) && $param['type'] > -1) {
                $query->where('order_status', $param['type']);
            }

            if (!empty($param['order_no'])) {
                $query->where('order_no', $param['order_no']);
            }

            if (!empty($param['delivery_no'])) {
                $query->where('delivery_no', $param['delivery_no']);
            }

            if (!empty($param['times'])) {
                $query->whereBetweenTime('add_time', strtotime($param['times'][0]), strtotime($param['times'][1]));
            }
        })->order('id desc')->paginate()->each(function ($v, $k) {
            $v['cn_status'] = OrderReceiptModel::getStatus($v['order_status']);
            $v['image'] = cmf_get_image_url($v['image']);
        });
        $this->success('ok', $list);
    }

    /**
     * 预购订单列表
     * @param $order_no
     * @param $p
     * @param array $time
     */
    public function get_purchase_list($order_no, $p, $time = [])
    {

    }

    /**
     * 预购消耗记录
     * @param $p
     * @param array $time
     */
    public function get_purchase_log($p, $time = [])
    {

    }

    /**
     * remark:
     * finance_remark: 123146
     * goods_list[0][goods_name]: 樟脑球
     * goods_list[0][goods_master_image]: http://daifatu.oss-cn-hangzhou.aliyuncs.com/shop/goods/2020_04_01/15857409972144.jpg
     * goods_list[0][goods_price]: 0.10
     * goods_list[0][weight]: 0.01
     * goods_list[0][goods_num]: 4621
     * goods_list[0][id]: 19
     * goods_list[0][goods_no]: ZNQ
     * goods_list[0][goods_storage][0][id]: 35
     * goods_list[0][goods_storage][0][sid]: 1
     * goods_list[0][goods_storage][0][storage_name]: 义乌仓储
     * goods_list[0][goods_storage][0][goods_id]: 19
     * goods_list[0][goods_storage][0][goods_num]: 4621
     * goods_list[0][image]: http://daifatu.oss-cn-hangzhou.aliyuncs.com/shop/goods/2020_04_01/15857409972144_400.jpg
     * goods_list[0][buy_num]: 1
     * goods_list[0][storage_id]: 1
     * goods_list[0][storage_name]: 义乌仓储
     * goods_list[0][storage_num]: 4621
     * real_list[0][order_no]: 800000000000
     * real_list[0][name]: 张三
     * real_list[0][tel]: 13900000000
     * real_list[0][area_info]: 浙江省 杭州市 西湖区 江南大道88号
     * real_list[1][order_no]: 800000000000
     * real_list[1][name]: 张三
     * real_list[1][tel]: 13900000000
     * real_list[1][area_info]: 浙江省 杭州市 西湖区 江南大道88号
     * real_list[2][order_no]: 800000000000
     * real_list[2][name]: 张三
     * real_list[2][tel]: 13900000000
     * real_list[2][area_info]: 浙江省 杭州市 西湖区 江南大道88号
     * real_list[3][order_no]: 800000000000
     * real_list[3][name]: 张三
     * real_list[3][tel]: 13900000000
     * real_list[3][area_info]: 浙江省 杭州市 西湖区 江南大道88号
     * is_cart: 0
     * import_mode: 手动输入
     * source_mode: 2
     * is_create: 1
     */


    public function create_order($finance_remark = '', $goods_id = 2, $real_list = [], $import_mode = '模板导入', $source_mode = 2, $storage_id)
    {
        /**
         * is_create: "1"
         * order_id: 62805
         * order_no: "2020061914361274682"
         */
        $goods = GoodsModel::find($goods_id);
        if (!$goods) {
            $this->error('商品不存在');
        }

        $storage_log = StorageLogModel::where(['goods_id' => $goods_id, 'sid' => $storage_id])->find();
        // if (!$storage_log) {
        //     $this->error('库存数据异常');
        // }
//        if ($storage['goods_num'] < count($real_list)) {
//            $this->error($storage['storage_name'] . '库存不足');
//        }

        $storage = StorageModel::find($storage_id);
        if (!$storage) {
            $this->error('仓库不存在');
        }
        $userInfo = Db::name('cloud_user')->where('id', 1)->where('logstate', 1)->find();
        if (!$userInfo) {
            $this->error('未查询到云仓账户，请联系管理');
        }
        Db::startTrans();
        $order_no = 'S' . cmf_get_order_sn(4);
        $total_price = ($goods['goods_price'] + $storage['price']) * count($real_list);
        $order_data = [
            'order_no'       => $order_no,
            'order_name'     => $goods['goods_name'],
            'add_time'       => time(),
            'finance_remark' => $finance_remark,
            'freight_money'  => $storage['price'],
            'image'          => $goods['image'],
            'import_mode'    => $import_mode,
            'order_price'    => $goods['goods_price'],
            'package_num'    => count($real_list),
            'source_mode'    => $source_mode,
            'total_price'    => $total_price,
            'user_id'        => $this->userId,
            'user_nickname'  => $this->user['user_nickname'],
            'mid'            => $goods['mid'],
            'goods_id'       => $goods_id,
            'storage_id'     => $storage_id,
        ];
        $order_id = Db::name('order')->insertGetId($order_data);
        if (!$order_id) {
            Db::rollback();
            $this->error('订单生成失败');
        }

        foreach ($real_list as &$item) {
            $item['add_time'] = time();
            $item['goods_name'] = $goods['goods_name'];
            $item['freight_money'] = $storage['price'];
            $item['image'] = $goods['image'];
            $item['obtain_order_no'] = $item['order'];
            
            $item['area_info'] = $item['province'].' '.$item['city'].' '.$item['area'].' '.$item['detail'];
            unset($item['order'], $item['province'], $item['city'], $item['area'], $item['detail']);
            
            $item['order_no'] = $order_no;
            $item['order_id'] = $order_id;
            $item['storage_name'] = $storage['store_name'];
            $item['total_price'] = $goods['goods_price'] + $storage['price'];
            $item['order_price'] = $goods['goods_price'];
            $item['user_id'] = $this->userId;
            $item['weight'] = $goods['weight'];
            $item['self_order_no'] = str_replace('S', 'R', $order_no) . random(5, true);
            $item['goods_id'] = $goods_id;
            $item['mid'] = $goods['mid'];
            $item['storage_id'] = $storage_id;
        }
        $num = Db::name('order_receipt')->insertAll($real_list);
        if (!$num) {
            Db::rollback();
            $this->error('包裹生成失败');
        }
        
        if ($goods['cloud_id'] > 0) {
            $ret = $this->cloud_create($order_id);
            if ($ret['code'] != 1) {
                Db::rollback();
                $this->error($ret['msg']);
            }
        }
        Db::commit();
        $this->success($ret['msg'] ?? 'ok', compact('order_id', 'order_no'));
    }
    
    private function cloud_create($order_id) 
    {
        $order = Db::name('order')->field('goods_id,storage_id,order_no,order_name as goods_name,image as goods_images,import_mode as order_type')->where('id', $order_id)->find();
        $goods = GoodsModel::get($order['goods_id']);
        $storage = StorageModel::get($order['storage_id']);
        $order['goods_id'] = $goods['cloud_id'];
        $order['storage_id'] = $storage['cloud_id'];
        if ($order['order_type'] === '一键发货') {
            $order['order_type'] = '-1';
        } else if ($order['order_type'] === '手动输入') {
            $order['order_type'] = '1';
        } else if ($order['order_type'] === '模板导入') {
            $order['order_type'] = '0';
        } else {
            $order['order_type'] = 1;
        }
        $receipt = Db::name('order_receipt')->field('self_order_no,obtain_order_no as third_order_no,name as receive_name,tel as receive_phone,area_info')->where('order_id', $order_id)->select();
        
        $real_list = [];
        foreach ($receipt as $k => $v) {
            $areaArr = explode(' ', $v['area_info']);
            $v['receive_province'] = $areaArr[0];
            $v['receive_city'] = $areaArr[1];
            $v['receive_town'] = $areaArr[2];
            $v['receive_address'] = $areaArr[3];
            unset($v['area_info']);
            array_push($real_list, json_encode($v, JSON_UNESCAPED_UNICODE));
        }
        $userInfo = Db::name('cloud_user')->where('id', 1)->where('logstate', 1)->find();
        $api = '/service/order/create_order';
        $args = array(
            'token' => $userInfo['token'],
            'goods_id' => $goods['cloud_id'],
            'storage_id' => $storage['cloud_id'],
            'orderData' => json_encode($order, JSON_UNESCAPED_UNICODE),
            'real_list' => json_encode($real_list),
            'platform' => 0,
            'order_type' => $order['order_type'],
        );
        $ret = json_decode($this->curlPost($api, http_build_query($args)), true);
        return $ret;
    }
    
    private function curlPost($api, $postdata) 
    {
        $url = "http://yuncangapi.maer.pro" . $api;
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT,300);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }
    
    private function cloud_pay($order_no)
    {
        $userInfo = Db::name('cloud_user')->where('id', 1)->where('logstate', 1)->find();
        $api = '/service/order/order_pay';
        $args = array(
            'token' => $userInfo['token'],
            'order_no' => $order_no
        );
        $ret = json_decode($this->curlPost($api, $args), true);
        return $ret;
    }
    
    private function loadErrBySn($order_no)
    {
        $userInfo = Db::name('cloud_user')->where('id', 1)->where('logstate', 1)->find();
        $api = '/service/order/loadErrBySn';
        $args = array(
            'token' => $userInfo['token'],
            'sn' => $order_no
        );
        $ret = json_decode($this->curlPost($api, $args), true);
        return $ret;
    }
    
    public function disposeAddress(string $send_list=null, string $op=null)
    {
        $address = htmlspecialchars_decode($send_list);
        $ret = _disposeAddress($address, $op);
        if ($ret['flag'] == 1) $this->success($ret['msg'], $ret['data']);
        $this->error($ret['msg']);
    }

    /**
     * @param $id
     * add_time: 1592548572
     * allow_status: 0
     * balance: "0.00"
     * close_time: 0
     * complete_time: 0
     * delivery_status: 0
     * delivery_time: 0
     * exclusive: "0.00"
     * finance_remark: "123146"
     * freight_money: "3.00"
     * id: 62805
     * image: "http://daifatu.oss-cn-hangzhou.aliyuncs.com/shop/goods/2020_04_01/15857409972144_200.jpg"
     * import_mode: "手动输入"
     * is_cart: 0
     * kid: 11
     * order_name: "樟脑球"
     * order_no: "2020061914361274682"
     * order_price: "0.10"
     * order_status: 0
     * package_num: 4
     * pay_status: 0
     * pay_time: 0
     * pay_type: ""
     * refund: 0
     * refund_delivery_no: ""
     * refund_info: ""
     * refund_no: ""
     * refund_status: 0
     * refund_step: 0
     * refund_time: 0
     * remark: ""
     * site_id: 3
     * source_mode: 2
     * total_price: "12.40"
     * user_id: 5925
     * user_nickname: "15558164462_4709"
     *
     */
    public function get_order_info($id)
    {
        $data = OrderModel::find($id);
        $this->success('ok', $data);
    }

    public function order_list_pay($id)
    {
        $order = OrderModel::where('id', $id)->find();
        if (!$order || $order['order_status'] != 0) {
            $this->error('不是待支付订单');
        }

        $total_price = $order['total_price'];
        $money = $this->user['balance'];
        if ($money < $total_price) {
            $this->error('余额不足');
        }
        
        $userInfo = Db::name('cloud_user')->where('id',1)->where('logstate',1)->find();
        if (!$userInfo) {
            $this->error('未查询到云仓账户，请联系管理');
        }

        Db::startTrans();
        if ($order['mid'] == 1) {
            $receipt = OrderReceiptModel::where('order_id', $id)->select();
            foreach ($receipt as $item) {
                list($province, $city, $district, $address) = explode(' ', $item['area_info']);
                $orders[] = [
                    'send_order_no'     => $item['self_order_no'],
                    'receiver_name'     => $item['name'],
                    'receiver_phone'    => $item['tel'],
                    'receiver_province' => $province,
                    'receiver_city'     => $city,
                    'receiver_district' => $district,
                    'receiver_address'  => $address,
                    'sendname'          => $this->user['user_nickname'],
                    'sendphone'         => $this->user['user_login'],
                ];
            }

            if (empty($orders)) {
                $this->error('包裹数据异常');
            }

            $manage = StorageManageModel::find($order['mid']);
            $client = new Client();
            try {
                $resp = $client->request('post', 'https://www.lipindao.com/api/goods/getmoney', [
                    'headers' => ['token' => $manage['token']],
                ]);
                $contents = ($resp->getBody()->getContents());
            } catch (\Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }

            $money_data = json_decode($contents, true);
            if ($money_data['data']['usermoney'] < $total_price) {
                Db::rollback();
                $this->error($manage['name'] . '平台余额不足，联系管理员充值');
            }

//                $storage = StorageModel::find($order['storage_id']);
//                $client = new Client();
//                try {
//                    $resp = $client->request('post', 'https://www.lipindao.com/api/goods/order', [
//                        'headers'     => ['token' => $manage['token']],
//                        'form_params' => [
//                            'send_order_no'     => $item['self_order_no'],
//                            'playtype'          => 1,
//                            'receiver_name'     => $item['name'],
//                            'receiver_phone'    => $item['tel'],
//                            'receiver_province' => $province,
//                            'receiver_city'     => $city,
//                            'receiver_district' => $district,
//                            'receiver_address'  => $address,
//                            'sendname'          => $this->user['user_nickname'],
//                            'sendphone'         => $this->user['user_login'],
//                            'goodsid'           => $goods['sid'],
//                            'storesid'          => $storage['sid']
//                        ]
//                    ]);
//
//                    $contents = ($resp->getBody()->getContents());
//                } catch (\Exception $e) {
//                    Db::rollback();
//                    $this->error($e->getMessage());
//                }
//
//                $data = json_decode($contents, true);
//                if ($data['code'] == 1) {
//                    $item->save(['taskid' => $data['data']['taskid'], 'taskp' => $data['data']['p'], 'msg' => $data['msg']]);
//                } else {
//                    $item->save(['taskmsg' => $data['msg']]);
//                }
//            }

            $goods = GoodsModel::find($order['goods_id']);
            $storage = StorageModel::find($order['storage_id']);

            try {
                $resp = $client->request('post', 'https://www.lipindao.com/api/goods/orders', [
                    'headers'     => ['token' => $manage['token']],
                    'form_params' => [
                        'goodsid'  => $goods['sid'],//第三方商品id
                        'storesid' => $storage['sid'],//第三方仓库id
                        'format'   => 'json',
                        'plattype' => 1,
                        'orders'   => json_encode($orders, JSON_UNESCAPED_UNICODE)
                    ]
                ]);
                $contents = ($resp->getBody()->getContents());
            } catch (\Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }

            $orders_data = json_decode($contents, true);
            if ($orders_data['code'] == 1) {
                $oklist = $orders_data['data']['okarr'];
                $errlist = $orders_data['data']['errarr'];
                if ($oklist) {
                    foreach ($oklist as $item) {
                        OrderReceiptModel::update(['taskid' => $item['taskid'], 'taskp' => $item['p']], ['self_order_no' => $item['send_order_no']]);
                    }
                }
                if ($errlist) {
                    foreach ($errlist as $item) {
                        OrderReceiptModel::update(['taskmsg' => $item['msg']], ['self_order_no' => $item['send_order_no']]);
                    }
                }
            } else {
                Db::rollback();
                $this->error($orders_data['msg']);
            }
        }

        $reData = [
            // 'delivery_name' => '圆通',
            // 'list' => [
            //     ['order_id' => "1444388484790724889",'delivery_code' => "1111111111"]
            // ]
        ];
        $goodsInfo = GoodsModel::find($order['goods_id']);
        if ($goodsInfo['cloud_id'] > 0) {
            $ret = $this->cloud_pay($order['order_no']);
            if ($ret['code'] != 1) {
                Db::rollback();
                $this->error($ret['msg']);
            } else {
                $reData = $ret['data'];
                $delivery_name = $ret['data']['delivery_name'];
                $receiptList = $ret['data']['list'];
                foreach ($receiptList as $v) {
                    OrderReceiptModel::update(['delivery_no' => $v['delivery_code'], 'delivery_company' => $delivery_name, 'delivery_time' => time(), 'order_status' => 1], ['obtain_order_no' => $v['order_id'],'order_no' => $order['order_no']]);// 已发货
                }
                $order->save(['order_status' => 3, 'pay_time' => time(), 'pay_status' => 1, 'pay_type' => 'money_pay']);// 已发货
            }
        }
        

        $rs1 = MoneyLogModel::addLog($this->userId, -$total_price, 3, '下单支付', $order['order_no']);
        if (!$rs1) {
            Db::rollback();
            $this->error(MoneyLogModel::getErrorInfo());
        }
        if ($goodsInfo['cloud_id'] == 0) {
            $rs2 = $order->save(['order_status' => 1, 'pay_time' => time(), 'pay_status' => 1, 'pay_type' => 'money_pay']);
            if (!$rs2) {
                Db::rollback();
                $this->error('订单状态更新失败');
            }
        }
        $rs3 = OrderReceiptModel::update(['show_status' => 1], ['order_id' => $id]);
        if (!$rs3) {
            Db::rollback();
            $this->error('包裹状态更新失败');
        }
        Db::commit();
        if ($goodsInfo['cloud_id'] > 0) $this->errRefund($order['order_no'], $order['user_id']);
        $this->success('支付成功', $reData);
    }
    
    private function errRefund($order_no, $uid)
    {
        $errRefundList = $this->loadErrBySn($order_no);
        if ($errRefundList['code'] == 1) {
            $errRefundList = $errRefundList['data'];
            $uInfo = Db::name('user')->where('id', $uid)->find();
            $orderInfo = OrderModel::get(['order_no' => $order_no]);
            foreach ($errRefundList as $v) {
                $pack = OrderReceiptModel::where(['obtain_order_no' => $v['third_order_no'],'self_order_no' => $v['package_no'],'order_no' => $order_no])->find();
                MoneyLogModel::addLog($uid, $pack['total_price'], 4, '包裹退款', $pack['self_order_no']);
                OrderReceiptModel::where('id', $pack['id'])->update(['order_status' => 3, 'taskmsg1' => $v['print_message'], 'refund_time' => time()]);
            }
            if ($orderInfo['package_num'] == count($errRefundList)) {
                OrderModel::where('id', $orderInfo['id'])->update(['order_status' => 5, 'refund_time' => time()]);
            }
        }
        return true;
    }

    public function change_order_status($id, $order_status)
    {
        if ($order_status > 5) {
            $order_status = 5;
        }
        $order = OrderModel::where('id', $id)->find();
        if ($order->save(['order_status' => $order_status])) {
            $this->success('ok');
        } else {
            $this->success('设置失败');
        }
    }

    public function excel_order($id)
    {
        set_time_limit(0);
        $order = OrderModel::find($id);
        if (!$order || $order['order_status'] < 3) {
            $this->error('没有发货记录');
        }
        $list = OrderReceiptModel::where('order_id', $id)->select();
        if (!$list->toArray()) {
            $this->error('没有包裹信息');
        }

        $fp = fopen('php://output', 'a+');
        $head = ['订单编号', '运单号', '快递公司', '收货人', '收货人电话', '收货地址', '备注信息'];
        foreach ($head as &$value) {
            $value = $this->i($value);
        }
        fputcsv($fp, $head);
        foreach ($list as $item) {
            $line = [$item->obtain_order_no, $item->delivery_no, $item->delivery_company, $item->name, $item->tel, $item->area_info, $item->title];
            foreach ($line as &$value) {
                $value = $this->i($value);
            }
            fputcsv($fp, $line);
        }

        $fileName = '订单信息' . date('ymdHis');
        header('Content-Type: application/vnd.ms-excel');   //header设置
        header("Content-Disposition: attachment;filename=" . $fileName . ".csv");
        header('Cache-Control: max-age=0');
        exit;
    }

    public function i($key)
    {
        return "\t" . iconv('UTF-8', 'GBK//IGNORE', $key);
    }
}